﻿using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace SqlSugarEncapsulation.Common
{
    public class SqlSugarBase<T> where T : class, new()
    {
        public ISqlSugarClient connection { get; private set; }

        public SqlSugarBase() : this(DBEnum.ADMP)
        {
        }

        public SqlSugarBase(DBEntity dbEntity)
        {
            this.connection = GetInstance(dbEntity);
        }

        private ISqlSugarClient GetInstance(DBEntity dbEntity)
        {
            //创建数据库对象
            SqlSugarClient db = new SqlSugarClient(new ConnectionConfig()
            {
                ConnectionString = dbEntity.ConnectionString,
                DbType = dbEntity.DBType,
                IsAutoCloseConnection = true,//自动释放和关闭数据库连接，如果有事务事务结束时关闭，否则每次操作后关闭
                InitKeyType = InitKeyType.Attribute//从特性读取主键自增信息
            });
            //设置超时时间为30秒
            db.Ado.CommandTimeOut = 30;

            //添加Sql打印事件，开发中可以删掉这个代码
            db.Aop.OnLogExecuting = (sql, pars) =>
            {
                //Console.WriteLine(sql);
            };
            return db;
        }

        /// <summary>
        /// 根据主键id查询
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual T GetById(dynamic id)
        {
            return connection.Queryable<T>().InSingle(id);
        }

        /// <summary>
        /// 根据条件获取第一行数据
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        public virtual T GetModel(Expression<Func<T, bool>> whereExpression)
        {
            //return connection.Queryable<T>().Single(whereExpression);
            return connection.Queryable<T>().Where(whereExpression).ToList().FirstOrDefault();
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <returns></returns>
        public virtual List<T> GetList()
        {
            return connection.Queryable<T>().ToList();
        }

        /// <summary>
        /// 根据主键获取列表
        /// </summary>
        /// <returns></returns>
        public virtual List<T> GetList(dynamic[] ids)
        {
            return connection.Queryable<T>().In(ids).ToList();
        }

        /// <summary>
        /// 根据条件获取列表
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        public virtual List<T> GetList(Expression<Func<T, bool>> whereExpression)
        {
            return connection.Queryable<T>().Where(whereExpression).ToList();
        }

        /// <summary>
        /// 根据条件分页排序查询
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <param name="page"></param>
        /// <param name="orderByExpression"></param>
        /// <param name="orderByType"></param>
        /// <returns></returns>
        public virtual List<T> GetPageList(Expression<Func<T, bool>> whereExpression, PageModel page, Expression<Func<T, object>> orderByExpression = null, OrderByType orderByType = OrderByType.Asc)
        {
            int count = 0;
            var result = connection.Queryable<T>().OrderByIF(orderByExpression != null, orderByExpression, orderByType).Where(whereExpression).ToPageList(page.PageIndex, page.PageSize, ref count);
            page.PageCount = count;
            return result;
        }

        /// <summary>
        /// 添加（Guid主键可以赋值/不赋值）
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public virtual bool Insert(T obj)
        {
            return connection.Insertable(obj).ExecuteCommand() > 0;
        }

        /// <summary>
        /// 批量添加（Guid主键可以赋值/不赋值）
        /// </summary>
        /// <param name="objs"></param>
        /// <returns></returns>
        public virtual bool InsertRange(List<T> objs)
        {
            return connection.Insertable(objs).ExecuteCommand() > 0;
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual bool Update(T obj)
        {
            return this.connection.Updateable(obj).ExecuteCommand() > 0;
        }

        /// <summary>
        /// 批量更新
        /// </summary>
        /// <param name="objs"></param>
        /// <returns></returns>
        public virtual bool UpdateRange(List<T> objs)
        {
            return this.connection.Updateable(objs).ExecuteCommand() > 0;
        }

        /// <summary>
        /// 根据主键id删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual bool DeleteById(dynamic id)
        {
            return this.connection.Deleteable<T>().In(id).ExecuteCommand() > 0;
        }

        /// <summary>
        /// 根据主键id批量删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public virtual bool DeleteByIds(dynamic[] ids)
        {
            return this.connection.Deleteable<T>().In(ids).ExecuteCommand() > 0;
        }

        /// <summary>
        /// 根据条件批量删除
        /// </summary>
        /// <param name="whereExpression"></param>
        /// <returns></returns>
        public virtual bool Delete(Expression<Func<T, bool>> whereExpression)
        {
            return this.connection.Deleteable<T>().Where(whereExpression).ExecuteCommand() > 0;
        }
    }
}
